﻿using System;
using System.Linq;
using Microsoft.SharePoint;

namespace Xodeuz.SP.Common
{
    public class SharePointList : Attribute
    {
        public string Name { get; set; }
        public SPListTemplateType Template { get; set; }
        public Type ItemModel { get; set; }

        public SharePointList(string name, SPListTemplateType template)
            : base()
        {
            this.Name = name;
            this.Template = template;
        }

        public SharePointList(string name, SPListTemplateType template, Type itemModel)
            : base()
        {
            this.Name = name;
            this.Template = template;
            this.ItemModel = itemModel;
        }

        public void EnsureList()
        {
            this.EnsureList(SPContext.Current.Web.Url, false, false);
        }

        public void EnsureList(string url)
        {
            this.EnsureList(url, false, false);
        }

        public void EnsureList(string url, bool force)
        {
            this.EnsureList(url, force, false);
        }

        public void EnsureList(string url, bool force, bool overridePermissions)
        {
            if (overridePermissions)
            {
                SPSecurity.RunWithElevatedPrivileges(delegate
                {
                    using(SPSite site = new SPSite(url))
                    using (SPWeb web = site.OpenWeb(url))
                    {
                        CreateList(force, web);
                    }
                });
            }
            else
            {
                using (SPSite site = new SPSite(url))
                using (SPWeb web = site.OpenWeb(url))
                {
                    CreateList(force, web);
                }
            }
        }

        private void CreateList(bool force, SPWeb web)
        {
            var list = web.Lists.TryGetList(this.Name);
            if (force && list != null)
            {
                list.Delete();
            }

            Guid listId = web.Lists.Add(this.Name, "", Template);
            list = web.Lists[listId];

            if (this.ItemModel != null)
            {
                var fieldCreations = ReflectionService.GetFieldCreations(ItemModel);
                foreach (var key in fieldCreations.Keys)
                {
                    if (ReadOnly.CreationFields.Contains(fieldCreations[key].InternalName)) continue;
                    String field = list.Fields.Add(fieldCreations[key].InternalName, fieldCreations[key].Type, false);

                    if (!String.IsNullOrEmpty(fieldCreations[key].DisplayName))
                    {
                        var newField = list.Fields.GetFieldByInternalName(field);
                        newField.Title = fieldCreations[key].DisplayName;
                        newField.Update();
                    }
                }
                list.Update();
            }
        }
    }
}
